package com.dyh.quickdemo.demos.lbdand;

import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/*
@Author=Joey Wheeler
@Date=2020/12/8 9:48
*/

@Slf4j
public class FcBreakerCenter {
    public static final Map<String,FcBreaker> name2Breaker = new ConcurrentHashMap<>();
    public static final Map<String,Statistics> name2Statistics = new ConcurrentHashMap<>();
    public static final Map<String,Boolean> name2CircuitBreake = new ConcurrentHashMap<>();
//    public short final Map<String,Long>
    /*是否熔断*/
    public static boolean isCircuitBreaked(String resourceName){
        return Optional.ofNullable(name2CircuitBreake.get(resourceName)).orElse(false);
    }

    public static void circuitBreake(String resourceName){
        name2CircuitBreake.put(resourceName,true);
    }

    public static void startStatistics(FcBreaker breaker){
       if (null == name2Breaker.get(breaker.resourceName))
           return;

        Statistics statistics;
       if (null == (statistics =name2Statistics.get(breaker.resourceName)) ){
           statistics = new Statistics();
           statistics.start();
           name2Statistics.putIfAbsent(breaker.resourceName,statistics);
       }
       else {
           if (statistics.startTimeMillis==0) statistics.start();//重新统计
           statistics.count();
       }
    }

    public static void collectMaxTime(String resourceName,long time){
        if (null == name2Breaker.get(resourceName))
            return;
        Statistics statistics;
        if (null == (statistics =name2Statistics.get(resourceName)) )
            return;
        if (time>statistics.maxTime){
            statistics.maxTime = time;
            statistics.maxTimeThreName = Thread.currentThread().getName();
        }
    }

    public static void endStatisticsIfTime(String resourceName){
        if (null == name2Breaker.get(resourceName))
            return;
        Statistics statistics;
        if (null == (statistics =name2Statistics.get(resourceName)) )
            return;
        if (TimeUtil.currentTimeMillis() > statistics.finishTime){
            endStatistics(resourceName);
        }
    }

    public static void endStatistics(String resourceName){
        if (null == name2Breaker.get(resourceName))
            return;
        Statistics statistics;
        if (null == (statistics =name2Statistics.get(resourceName)) )
            return;
        log.info("统计时间:{} ms 请求数:{} 耗时最长线程:{} 耗时:{} ms",
                TimeUtil.currentTimeMillis()-statistics.startTimeMillis,statistics.count,
                statistics.maxTimeThreName,statistics.maxTime);
        statistics.end();
    }

//    public static void endStatistics(FcBreaker breaker){
//        if (null == name2Breaker.get(breaker.resourceName))
//            return;
//        Statistics statistics;
//        if (null == (statistics =name2Statistics.get(breaker.resourceName)) )
//            return;
//        statistics.end();
//    }

    public static FcBreaker find(String resourceName){
        return name2Breaker.get(resourceName);
    }

    public static void registIfAbsent(FcBreaker breaker){
        /*breaker.resourceName==null =>NPE*/
        name2Breaker.putIfAbsent(breaker.resourceName,breaker);
    }
}
